package com.mh.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.mh.dao.UserInfoDao;
import com.mh.dto.R;
import com.mh.dto.bo.UpdateReceiverBo;
import com.mh.dto.vo.FriendsInfoDto;
import com.mh.dto.vo.LoginDataReturn;
import com.mh.dto.vo.LoginVo;
import com.mh.pojo.Friends;
import com.mh.pojo.UserInfo;
import com.mh.service.UserInfoService;
import com.mh.utils.EmailUtil;
import com.mh.utils.JWTUtils;
import lombok.RequiredArgsConstructor;
import org.apache.catalina.User;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.stereotype.Service;

import java.util.HashMap;
import java.util.Map;
import java.util.UUID;

/**
 * 用户信息表(UserInfo)表服务实现类
 *
 * @author zmh
 * @since 2024-09-02 17:22:05
 */
@Service
@RequiredArgsConstructor
public class UserInfoServiceImpl extends ServiceImpl<UserInfoDao, UserInfo> implements UserInfoService {

    @Autowired
    private UserInfoDao userInfoDao;

    // 邮件工具类
    private final EmailUtil emailUtil;

    // 强散列密码编码器
    private final PasswordEncoder passwordEncoder;

    // Redis
    private final RedisTemplate<String, String> redisTemplate;

    private final RabbitTemplate rabbitTemplate;

    /**
     * 分页查询
     *
     * @param page 查询页数
     * @param size 一页显示条数
     * @return ·
     */
    public R<Page<UserInfo>> getAllByPage(int page, int size) {
        Page<UserInfo> userInfoPage = new Page<>(page, size);
        LambdaQueryWrapper<UserInfo> queryWrapper = new LambdaQueryWrapper<>();
        //TODO 查询条件定制
        return R.success(userInfoDao.selectPage(userInfoPage, queryWrapper));
    }

    // 登录验证
    @Override
    public Map<String, Object> loginCheck(LoginVo loginArgs) {
        // 创建一个map，用于封装返回
        Map<String, Object> map = new HashMap<>();

        // 查询数据库，判定用户是否存在或密码是否正确
        LambdaQueryWrapper<UserInfo> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(UserInfo::getEmail, loginArgs.getEmail());
        UserInfo user = userInfoDao.selectOne(queryWrapper);
        if(user == null){
            map.put("errMsg", "用户不存在");
            return map;
        }
        // 用户存在，检查登录密码
        if(!passwordEncoder.matches(loginArgs.getPassword(),user.getPassword())){
            map.put("errMsg", "密码错误");
            return map;
        }

        // 验证成功，返回用户信息和token
        map.put("token", JWTUtils.createToken(user.getUserId()));
        // 将用户信息排除password字段后，copy给用于返回的dto对象
        LoginDataReturn loginDataReturn = new LoginDataReturn();
        BeanUtils.copyProperties(user, loginDataReturn);
        map.put("userInfo", loginDataReturn);
        return map;
    }

    @Override
    public R<String> addUser(UserInfo userInfo, String code) {
        // 检查用户邮箱，查看用户是否已经注册
        LambdaQueryWrapper<UserInfo> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(UserInfo::getEmail, userInfo.getEmail());
        UserInfo userInfo1 = userInfoDao.selectOne(queryWrapper);
        if(userInfo1 != null){
            return R.error("用户已存在");
        }

        // 验证邮箱验证码
        if(!emailUtil.verificationEmailCode(userInfo.getEmail(), code)){
            return R.error("验证码失效或错误");
        }

        // 填充用户ID，加密密码
        userInfo.setUserId(UUID.randomUUID().toString());
        userInfo.setPassword(passwordEncoder.encode(userInfo.getPassword()));
        // 执行新增
        int insert = userInfoDao.insert(userInfo);

        if(insert > 0){
            // 新增成功之后将验证码删除
            redisTemplate.delete(userInfo.getEmail());
            // 通知RabbitMQ，动态Redis中维护接收者信息列表
            rabbitTemplate.convertAndSend("update-receiver-queue",
                    new UpdateReceiverBo(userInfo.getUserId(),userInfo.getName(),"add"));
            return R.success("新增成功");
        }
        return R.error("新增失败");
    }

    // 根据邮箱地址搜索用户
    @Override
    public UserInfo getUserByEmail(String email) {
        LambdaQueryWrapper<UserInfo> queryWrapper = new LambdaQueryWrapper<UserInfo>().eq(UserInfo::getEmail, email);
        UserInfo userInfo = userInfoDao.selectOne(queryWrapper);
        if(userInfo == null){
            return new UserInfo(); // 返回空对象-代表搜索用户不存在
        }
        return userInfo;
    }

    @Override
    public Boolean checkId(String userId) {
        LambdaQueryWrapper<UserInfo> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(UserInfo::getUserId, userId);
        UserInfo userInfo = userInfoDao.selectOne(queryWrapper);
        return userInfo != null;
    }

    // 根据用户ID查询用户名称
    @Override
    public R<String> getNameByUserId(String userId) {
        String userName = userInfoDao.selectUserNameByUserId(userId);
        if(userName != null){
            return R.success(userName);
        }
        return R.error("用户不存在");
    }
}

